﻿//#define _CRT_SECURE_NO_WARNINGS 1
//#include<iostream>
//using namespace std;
//
//
////int& Add(int a, int b)
////{
////	int c = a + b;
////	return c;
////}
////int main()
////{
////	//int a = 10;
////	//int x = 20;
////	//int& b = a;
////	//int& f = a;
////	//int c = b;//赋值
////	//cout << a << endl << b <<endl<< c  << endl << f <<endl;
////	//cout << &a <<endl << &b <<endl<< &c  << endl;
////
////	int a = 10, b = 20;
////	int& c = a;
////	int& d = b;
////	int x = Add(a, b);
////	int y = Add(10, 20);
////	cout << x <<endl <<y  << endl;
////	return 0;
////}
//
////int main()
////{
//	//int a = 10;
//	//const int& b = a;//权限可以缩小
//	////int& d = b;错误写法，权限不能放大
//	//int& c = a;
//	//cout << b << endl << c<< endl;
//	//a = 20;//引用的权限缩小不改变原来的权限
//	//cout << b << endl << c<< endl;
//
//	//以下还是符合权限不能放大的逻辑
//	//int b = 20;
//	//const int& a = 30;//牛逼 const可以给常量取别名
//	//const int& c = a + b;//拷贝行为，不存在权限放大，a + b 的结果是一个临时变量，具有常性
//	//cout << a << endl << b << endl << c << endl;
//
//	//double xa = 1.12345;
//	//int xb = xa;
//	//double& rxx = xa;
//
//	////此处引用的是在double变成int时候产生的临时变量，被const引用的临时变量和const引用生命周期一样
//	//const int& rxa = xa;
//	//cout << xa << endl << rxx << endl << xb << endl << rxa << endl;
//
//	/*int* p = NULL;
//	int& b = *p;*/
//
//
////	return 0;
////}
//
//int main()
//{
//	/*cout << "dcscc ajdscnac \n"<< endl;
//	cout << "sas";*/
//
//	int a = 10;
//	int* p = &a;
//	cout << *p << endl;
//	p = nullptr;
//	//p = NULL;
//	//cout << *p << endl;
//	return 0;
//}

#include<iostream>
#include<assert.h>
using namespace std;
//class Stack
//{
//	//公有
//	public:
//		// 成员函数
//		void Init(int n = 4)
//		{
//			array = (int*)malloc(sizeof(int) * n);
//			if (nullptr == array)
//			{
//				perror("malloc申请空间失败");
//				return;
//			}
//			capacity = n;
//			top = 0;
//		}
//		void Push(int x)
//		{
//			// ...扩容
//			array[top++] = x;
//		}
//
//		int Top()
//		{
//			assert(top > 0);
//			return array[top - 1];
//		}
//		void Destroy()
//		{
//			free(array);
//			array = nullptr;
//			top = capacity = 0;
//		}
//	//私有
//	private:
//		// 成员变量
//		int* array;
//		size_t capacity;
//		size_t top;
//}; // 分号不能省略
//int main()
//{
//	Stack st;
//	st.Init();
//	st.Push(1);
//	st.Push(2);
//	cout << st.Top() << endl;
//	st.Destroy();
//	return 0;
//}

//class Stack
//{
//public:
//	int _a;
//	int _b;
//
//	void Init(int a, int b)
//	{
//		_a = a;
//		_b = b;
//	}
//
//	void print()
//	{
//		//this指针一般认为存在栈里面,在此处VS里放在寄存器里面(因为要高频使用)
//		cout << this->_a << this->_b << endl;
//	}
//};
//int main()
//{
//	Stack sd;
//	sd.Init(1, 2);
//	sd.print();
//	return 0;
//}

//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	void Print()
//	{
//		cout << this << endl;
//		cout << "A::Print()" << endl;
//	}
////private:
//	int _a;
//};
//int main()
//{
//	A* p = nullptr;
//
//	//这里不报错是因为会隐含的传this指针 而且没有解引用，所以没有报错 ->箭头不代表一定解引用
//	p->Print();
//	p->_a = 1;//此处解引用，是严重错误行为
//
//	return 0;
//}

//class A
//{
//public:
//	void Print()
//	{
//		cout << "A::Print()" << endl;
//		//这里this指针发生解引用崩溃了  发生了解引用行为
//		cout << _a << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	A* p = nullptr;
//	p->Print();
//	return 0;
//}

//class KK
//{
//public:
//	int _a, _b, _c;
//	/*KK()
//	{
//		_a = 1;
//		_b = 2;
//		_c = 3;
//	}
//	KK(int a, int b, int c)
//	{
//		_a = a;
//		_b = b;
//		_c = c;
//	}*/
//	KK(int a = 1, int b = 1, int c = 1)//全缺省默认构造函数
//	{
//		_a = a;
//		_b = b;
//		_c = c;
//	}
//	void Init(int a, int b, int c)
//	{
//		_a = a;
//		_b = b;
//		_c = c;
//	}
//	void print()
//	{
//		cout << _a << " " << _b << " " << _c << endl;
//	}
//	
//};
//int main()
//{
//	KK kk(2, 2, 2);
//	kk.print();
//
//	return 0;
//}

//class KK
//{
//public:
//	KK(int year = 2000, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	int Getyear()
//	{
//		return _year;
//	}
//	int Getmonth()
//	{
//		return _month;
//	}
//	int Getday()
//	{
//		return _day;
//	}
//	bool operator==(KK k2)
//	{
//		return _year == k2._year && _month == k2._month && _day == k2._day;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
////bool operator==(KK k1, KK k2)
////{
////	return k1._year == k2._year && k1._month == k2._month && k1._day == k2._day;
////}
////bool operator==(KK k1, KK k2)
////{
////	return k1.Getyear() == k2.Getyear() && k1.Getmonth() == k2.Getmonth() && k1.Getday() == k2.Getday();
////}
////operator
//int main()
//{
//	KK k1(2025, 11, 2);
//	KK k2(2025, 11, 1);
//
//	operator==(k2);
//	bool x = k1 == k2;
//	printf("%d\n", x);
//
//	return 0;
//}

//class KK
//{
//public:
//	KK(int year = 0, int month = 0, int day = 0)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void print()
//	{
//		cout << _year << " " << _month << " " << _day << endl;
//	}
//	//拷贝构造函数
//	KK(const KK& d)
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	KK k1(2005, 11, 20);
//	k1.print();
//	KK k2(k1);
//	k2.print();
//
//
//	return 0;
//}
//class KK
//{
//
//};
////函数返回引用时候对象(资源)必须在函数结束以后还存在
//int Add(int& x, int& y)
//{
//	return x + y;
//}
//int main()
//{
//	int x = 1, y = 2;																																																											
//	int z = Add(x, y);
//	cout << z << endl;
//	return 0;
//}

//class KK
//{
//public:
//	KK(int year = 0, int month = 0, int day = 0)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void print()
//	{
//		cout << "Hello World!" << endl;
//	}
////private:
//	int _year;
//	int _month;
//	int _day;
//};
////把成员公有的办法
//bool operator==(const KK& k1, const KK& k2)
//{
//	return k1._year == k2._year && k1._month == k2._month && k2._day == k1._day;
//}
//
//typedef void(KK::* PF)();
//int main()
//{
//	// 如果没有typedef 下下一行完整版应该这样写 
//	// void(KK:: * p)() = &KK::print;
//	PF p = nullptr;
//	p = &KK::print;
//	//KK k;
//	////成员函数的回调
//	//(k.*p)();
//	KK k1(1, 11, 11);
//	KK k2(1, 1, 11);
//	bool x = (k1 == k2);
//	printf("%d\n", x);
//
//	return 0;
//}

//class KK
//{
//public:
//	KK(int year = 0, int month = 0, int day = 0)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void print()
//	{
//		cout << "Hello World!" << endl;
//	}
//	int getyear() const
//	{
//		return _year;
//	}
//	int getmonth() const
//	{
//		return _month;
//	}
//	int getday() const
//	{
//		return _day;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
////提供get函数的方法
//bool operator==(const KK& k1, const KK& k2)
//{
//	return k1.getyear() == k2.getyear() && k1.getmonth() == k2.getmonth() && k1.getday() == k2.getday();
//}
//
//typedef void(KK::* PF)();
//int main()
//{
//	// 如果没有typedef 下下一行完整版应该这样写 
//	// void(KK:: * p)() = &KK::print;
//	PF p = nullptr;
//	p = &KK::print;
//	//KK k;
//	////成员函数的回调
//	//(k.*p)();
//	KK k1(1, 11, 11);
//	KK k2(1, 1, 11);
//	bool x = (k1 == k2);
//	printf("%d\n", x);
//
//	return 0;
//}

//class KK
//{
//public:
//	KK(int year = 0, int month = 0, int day = 0)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void print()
//	{
//		cout << "Hello World!" << endl;
//	}
//	//重载为成员函数
//	bool operator==(const KK& k2)
//		{
//			return _year == k2._year && _month == k2._month && k2._day == _day;
//		}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//typedef void(KK::* PF)();
//int main()
//{
//	// 如果没有typedef 下下一行完整版应该这样写 
//	// void(KK:: * p)() = &KK::print;
//	PF p = nullptr;
//	p = &KK::print;
//	//KK k;
//	////成员函数的回调
//	//(k.*p)();
//	KK k1(1, 11, 11);
//	KK k2(1, 1, 11);
//	bool x = (k1 == k2);
//	printf("%d\n", x);
//
//	return 0;
//}
//
//class KK
//{
//public:
//	KK(int year = 0, int month = 0, int day = 0)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void print()
//	{
//		cout << "Hello World!" << endl;
//	}
//	KK& operator=(const KK& k1)
//	{
//		_year = k1._year;
//		_month = k1._month;
//		_day = k1._day;
//
//		return *this;
//	}
//	//重载为成员函数
//	bool operator==(const KK& k2)
//	{
//		return _year == k2._year && _month == k2._month && k2._day == _day;
//	}
//	//成员函数重载
//	int operator+(const KK& k2)
//	{
//		return _year + k2._year;
//	}
//	//成员函数重载
//	int operator-(const KK& k2)
//	{
//		return _year - k2._year;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//typedef void(KK::* PF)();
//int main()
//{
//	// 如果没有typedef 下下一行完整版应该这样写 
//	// void(KK:: * p)() = &KK::print;
//	PF p = nullptr;
//	p = &KK::print;
//
//	KK k;
//	//成员函数的回调
//	(k.*p)();
//
//	KK k1(10, 11, 11);
//	KK k2(1, 1, 11);
//	bool x = k1.operator==(k2);
//	x = (k1 == k2);
//	cout << x << endl;
//
//	int y = k1.operator+(k2);
//	y = k1 - k2;
//	cout << y << endl;
//
//	//拷贝构造
//	KK k3(k1);
//	KK k4 = k2;
//
//	//拷贝赋值
//	//下面两句等价，都是把已经存在的k2的值赋给已经存在的k3
//	k3 = k2;
//	k3.operator=(k2);
//
//	return 0;
//}


//class Date
//{
//public:
//
//
//
//private:
//	int _year;
//	int _month;
//	int _day;
//};

//class Time
//{
//public:
//	Time(int hour)
//		:_hour(hour)
//	{
//		cout << "Time()" << endl;
//	}
//private:
//	int _hour;
//};
//class Date
//{
//public:
//	Date(int& x, int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//		, _t(12)
//		, _ref(x)
//		, _n(1)
//	{
//		// error C2512: “Time”: 没有合适的默认构造函数可⽤
//		// error C2530 : “Date::_ref” : 必须初始化引⽤
//		// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象
//	}
//	void Print() const
//	{
//	cout << _year << "-" << _month << "-" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//	Time _t; // 没有默认构造
//	int& _ref; // 引⽤
//	const int _n; // const
//};
//int main()
//{
//	int i = 0;
//	Date d1(i);
//	d1.Print();	
//	return 0;
//}

//class A
//	 {
// public:
//	 A(int a)//1
//		 : _a1(a)//1
//		, _a2(_a1)
//	{}
//	void Print() 
//	{
//		cout << _a1 << " " << _a2 << endl;
//	}
//private:
//	int _a2 = 2;
//	int _a1 = 2;
//};
//int main()
//{
//	A aa(1);
//	aa.Print();
//}

//class A
//{
//public:
//	A()
//	{
//		++_scount;
//	}
//	A(const A& t)
//	{
//		++_scount;
//	}
//	~A()
//	{
//		--_scount;
//	}
//	static int GetACount()
//	{
//		return _scount;
//	}
//private:
//	// 类⾥⾯声明
//	static int _scount;
//};
//// 类外⾯初始化
//int A::_scount = 0;
//
//int main()
//{
//	cout << A::GetACount() << endl;
//	A a1, a2;
//	A a3(a1);
//	cout << A::GetACount() << endl;
//	cout << a1.GetACount() << endl;
//	
//		// 编译报错：error C2248: “A::_scount”: ⽆法访问 private 成员(在“A”类中声明)
//		//cout << A::_scount << endl;
//		
//		 return 0;
//}


//class A
//{
//private:
//	static int _k;
//	int _h = 1;
//public:
//	class B // B默认就是A的友元
//	{
//	public:
//		void foo(const A& a)
//		{
//			cout << _k << endl; //OK
//			cout << a._h << endl; //OK
//		}
//		int _b1;
//	};
//};
//int A::_k = 1;
//int main()
//{
//	cout << sizeof(A) << endl;
//
//	A::B b;
//	A aa;
//	b.foo(aa);
//	cout << sizeof(A) << endl;
//	cout << sizeof(A::B) << endl;
//	return 0;
//}


//class A
//{
//public:
//	A(int a = 0)
//		 : _a(a)
//		 {
//			cout << "A(int a)" << endl;
//		 }
//	
//		 ~A()
//		 { 
//			cout << "~A()" << endl;
//		 }
// private:
// int _a;
//};
//
// class Solution 
// {
// public:
//	int Sum_Solution(int n) 
//	{
//		 //...
//			 return n;
//		
//	}
//	
//};
//int main()
//{
//	 A aa1;
//	 // 不能这么定义对象，因为编译器⽆法识别下⾯是⼀个函数声明，还是对象定义
//	 //A aa1();
//	
//	 // 但是我们可以这么定义匿名对象，匿名对象的特点不⽤取名字，
//		 // 但是他的⽣命周期只有这⼀⾏，我们可以看到下⼀⾏他就会⾃动调⽤析构函数
//	 A();
//	 A(1);
//	
//	 A aa2(2);
//
//	 // 匿名对象在这样场景下就很好⽤，当然还有⼀些其他使⽤场景，这个我们以后遇到了再说
//	Solution().Sum_Solution(10);
//
//	return 0;
//}


class A
{
public:
	A(int a = 0)
		:_a1(a)
	{
		cout << "A(int a)" << endl;
	}
	A(const A& aa)
		:_a1(aa._a1)
	{
		cout << "A(const A& aa)" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa)
		{
			_a1 = aa._a1;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a1 = 1;
};

 void f1(A aa)
 {}

 A f2()
 {
 A aa;
 return aa; }

 int main()
 {
	// 传值传参 // 构造+拷⻉构造
	A aa1;
	f1(aa1);
	cout << endl;

	// 隐式类型，连续构造+拷⻉构造->优化为直接构造
	f1(1);

	// ⼀个表达式中，连续构造+拷⻉构造->优化为⼀个构造
	f1(A(2));
	cout << endl;

	cout << "***********************************************" << endl;

	// 传值返回
	// 不优化的情况下传值返回，编译器会⽣成⼀个拷⻉返回对象的临时对象作为函数调⽤表式的返回值

	// ⽆优化 （vs2019 debug）
	// ⼀些编译器会优化得更厉害，将构造的局部对象和拷⻉构造的临时对象优化为直接构造
	//（vs2022 debug）
	f2();
	cout << endl;

	// 返回时⼀个表达式中，连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 （vs2019 debug）
	// ⼀些编译器会优化得更厉害，进⾏跨⾏合并优化，将构造的局部对象aa和拷⻉的临时对象和接收返回值对象aa2优化为⼀个直接构造。（vs2022 debug）
	A aa2 = f2();
	cout << endl;

	// ⼀个表达式中，开始构造，中间拷⻉构造+赋值重载->⽆法优化（vs2019 debug）
	// ⼀些编译器会优化得更厉害，进⾏跨⾏合并优化，将构造的局部对象aa和拷⻉临时对象合并为⼀个直接构造（vs2022 debug）
	aa1 = f2();
	cout << endl;
	return 0;
 }